package com.gingersoft.connect.bean

import com.gingersoft.connect.SendCallback
import com.gingersoft.connect.utils.GingerSoftConnect
import com.gingersoft.connect.utils.GsonUtils
import com.gingersoft.connect.utils.MyWebSocketClient
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking

class MessageSender(
    private val connect: GingerSoftConnect,
    private val webSocketClient: MyWebSocketClient,
    private val msg: MessageBean
) {

    fun send(): GingerSoftConnect {
        asyncSend(null)
        return connect
    }

    /**
     * 發送數據到服務器
     * @param callback Function1<Boolean, Unit> 回調，只能保證是否發送，不能保證對方是否接收到
     * @return GingerSoftConnect
     */
    fun send(callback: (Boolean) -> Unit): GingerSoftConnect {
        if (webSocketClient.isOpen) {
            asyncSend(null)
            callback.invoke(true)
        } else {
            callback.invoke(false)
        }
        return connect
    }

    /**
     * 發送到服務器，對方正常接收到數據會通知過來
     * @return GingerSoftConnect
     */
    fun asyncSend(callback: SendCallback?): GingerSoftConnect {
        val currentTimeMillis = System.currentTimeMillis()
        runBlocking {
            launch(Dispatchers.IO) {
                while (webSocketClient.getStatus() == 0 && System.currentTimeMillis() - currentTimeMillis < 10000) {
                    delay(500)
                }
                if (webSocketClient.getStatus() != 0) {
                    send(callback)
                } else {
                    // 超時
                    callback?.callback(false, MessageBuilder.ERROR_CODE_CONNECT_TIMEOUT, "連接超時")
                }
            }
        }
        return connect
    }

    private fun send(callback: SendCallback?) {
        if (webSocketClient.isClosed || webSocketClient.isClosing || !webSocketClient.isOpen) {
            callback?.callback(false, MessageBuilder.ERROR_CODE_NOT_CONNECT, "未連接設備")
        } else {
            webSocketClient.sendMsg(msg.code.toString(), GsonUtils.GsonString(msg), callback)
        }
    }
}